#import "FlutterBuglyPlugin.h"
#import <Bugly/Bugly.h>

@implementation FlutterBuglyPlugin

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
    FlutterMethodChannel *channel = [FlutterMethodChannel
                                     methodChannelWithName:@"flutter_bugly_plugin"
                                           binaryMessenger:[registrar messenger]];
    FlutterBuglyPlugin *instance = [[FlutterBuglyPlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
    if ([@"initBugly" isEqualToString:call.method]) {
        NSDictionary *arguments = call.arguments;
        if (![arguments isKindOfClass:[NSDictionary class]]) {
            result([NSNumber numberWithBool:false]);
            return;
        }
        NSString *appId = [self stringForKey:@"appId" withDictionary:arguments];
        if (!appId) {
            result([NSNumber numberWithBool:false]);
            return;
        }

        BuglyConfig *config = [[BuglyConfig alloc] init];
        config.blockMonitorEnable = YES;
        config.reportLogLevel = BuglyLogLevelWarn;

    #if DEBUG
        config.blockMonitorEnable = YES;
        config.blockMonitorTimeout = 1.5;
        [Bugly startWithAppId:appId config:config];
    #else
        [Bugly startWithAppId:appId config:config];
    #endif

        result([NSNumber numberWithBool:true]);
    } else if ([@"postCrash" isEqualToString:call.method]) {
        NSDictionary *arguments = call.arguments;
        if (![arguments isKindOfClass:[NSDictionary class]]) {
            result([NSNumber numberWithBool:false]);
            return;
        }
        NSString *crashMessage = [self stringForKey:@"crashMessage" withDictionary:arguments] ? : @"";
        NSString *crashStack = [self stringForKey:@"crashStack" withDictionary:arguments] ? : @"";
        [Bugly reportExceptionWithCategory:3 name:crashMessage reason:@"" callStack:@[crashStack] extraInfo:@{} terminateApp:NO];
        result([NSNumber numberWithBool:true]);
    } else {
        result(FlutterMethodNotImplemented);
    }
}

- (id)stringForKey:(id)key withDictionary:(NSDictionary *)target {
    id value = [self safeObjectForKey:key class:[NSString class]  withDictionary:target];
    return value;
}

- (id)safeObjectForKey:(id)key class:(Class)aClass withDictionary:(NSDictionary *)target {
    id value = [self safeObjectForKey:key withDictionary:target];
    if ([value isKindOfClass:aClass]) {
        return value;
    }
    return nil;
}

- (id)safeObjectForKey:(id)key withDictionary:(NSDictionary *)target {
    if (![target isKindOfClass:[NSDictionary class]]) {
        return nil;
    }
    if (key == nil) {
        return nil;
    }
    id value = [target objectForKey:key];
    if (value == [NSNull null]) {
        return nil;
    }
    return value;
}

@end
